import { getDictByCode } from '@/services/system/dict';
import { PageType, Result, ResultList } from '@/types/common/request';
import { StrUtil } from '@/util/msg';
import { createIcon } from '.';
import moment from 'moment';

/**
 *  请求接口，返回接口数据
 * @param {() => Promise<PageType<T>>} server
 * @returns {Promise<T[]>}
 */
export const getApiData = async <T>(server: () => Promise<PageType<T>>) => {
  const ret = await server();
  return ret.data;
};

export type SelectType<K = string> = { label: K; value: K };
type SelectListProps<T, K> = {
  server: () => Promise<K>;
  label: keyof T;
  value: keyof T;
};

/**
 * 获取getDictSelectList的默认参数格式
 * @param {string} code
 * @returns {SelectListProps<DICT_TYPE.Info, ResultList<DICT_TYPE.Info>>}
 */
export const getDefaultSelectListProps = (
  code: string,
): SelectListProps<DICT_TYPE.Info, ResultList<DICT_TYPE.Info>> => {
  return {
    label: 'title',
    value: 'value',
    server: () => getDictByCode(code),
  };
};

/**
 * 根据提供的类型和服务器请求，获取下拉选择列表的数据。
 * @param {SelectListProps<T, K>} 参数对象，包含以下属性：
 *  - server: 异步函数，用于请求数据的服务器调用。
 *  - label: 显示的属性名。
 *  - value: 值的属性名。
 * @returns {Promise<SelectType<T[keyof T]>[]>} 返回一个Promise，解析为选择列表项数组，
 *  每个列表项包含 `label` 和 `value` 属性。
 */
export const getSelectList = async <T = DICT_TYPE.Info, K extends Result<T[]> = Result<T[]>>({
  server,
  label,
  value,
}: SelectListProps<T, K>): Promise<SelectType<string>[]> => {
  const ret = await server();
  return ret.data.map((c): SelectType<string> => {
    return {
      label: c[label] as string,
      value: c[value] as string,
    };
  });
};

/**
 * 递归遍历树形数据，将所有节点合并成一个扁平数组
 * @param {T extends TreeNode[]} nodes
 * @returns {T[]}
 */
export function flattenTree<T extends TreeNode>(nodes: T[]): T[] {
  let result: T[] = [];
  nodes.forEach((node) => {
    // 将当前节点添加到结果数组中
    result.push(node);
    // 如果当前节点有子节点，递归调用 flattenTree 并合并结果
    if (node.children) {
      result = result.concat(flattenTree(node.children));
    }
  });
  return result;
}

/**
 * 获取树形数据中的所有节点的 key 列表
 * @param {T[]} nodes
 * @param {keyof T} key
 * @param {boolean} all
 * @returns {string[]}
 */
export function getTreeKeyList<T extends TreeNode>(
  nodes: T[],
  key: keyof T = 'id',
  all = false,
): string[] {
  let result: string[] = [];
  nodes.forEach((node) => {
    if (all) result.push(node[key] as string);
    // 如果当前节点有子节点，递归调用 flattenTree 并合并结果
    if (node.children) {
      // 将当前节点添加到结果数组中
      if (!all) result.push(node[key] as string);
      result = result.concat(getTreeKeyList(node.children, key, all));
    }
  });
  return result;
}

/**
 * 表单项获取数据格式化
 * @param value
 * @returns {any}
 */
export const convertValue = (value: any) => {
  return value && typeof value === 'string' ? value.split(StrUtil.COMMIT) : value;
};

/**
 * 表单项提交数据格式化
 * @param value
 * @returns {any}
 */
export const transformValue = (value: any) => {
  return value && typeof value === 'object' ? value.join(StrUtil.COMMIT) : value;
};

type RouterType = {
  list: any[];
  pathList: string[];
};

export function formatRouter(pre?: any[]): RouterType {
  const data: RouterType = {
    list: [],
    pathList: [],
  };
  // 非空判断
  if (pre && pre.length) {
    let s: any = {};
    pre.forEach((c) => {
      s = { ...c };
      if (s.title) s.name = s.title;
      if (s.code && !s.routerPath) s.routerPath = StrUtil.SLASH + s.code;
      s.path = s.routerPath || s.path;
      // if (s.filePath) s.component = require(`@/pages${s.filePath}`).default;
      // if (s.filePath) s.component = StrUtil.DOT + s.filePath;
      s.icon = createIcon(s.icon || s.iconName || '');
      if (s.children && s.children.length > 0) {
        const childrenData = formatRouter(s.children);
        data.pathList.push(...childrenData.pathList);
        childrenData.list.unshift({
          path: s.path,
          redirect: childrenData.list[0].path,
        });
        s.children = childrenData.list;
      }
      delete s.target;
      data.pathList.push(s.path);
      data.list.push(s);
    });
  }
  return data;
}

/**
 * 根据出生日期计算年龄
 * @param date
 * @returns
 */
export const onBirthdayChange = (date: string) => {
  return Math.ceil(moment.duration(moment().diff(moment(date))).asYears());
};

/**
 * 根据身份证计算出生日期，性别，年龄
 * @param idCard
 * @returns
 */
export const onIdCardChange = (idCard: string) => {
  const year = parseInt(idCard.substring(6, 10), 10);
  const month = parseInt(idCard.substring(10, 12), 10);
  const day = parseInt(idCard.substring(12, 14), 10);
  const birthday = `${year}-${month.toString().padStart(2, '0')}-${day
    .toString()
    .padStart(2, '0')}`;
  const sex = parseInt(idCard.charAt(16), 10) % 2 === 0 ? 'female' : 'male';
  let age = 0;
  if (birthday) {
    age = onBirthdayChange(birthday);
  }
  return { birthday, sex, age };
};
